package com.cxj.cxj_test_cloud.common.di.component;

import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;

import com.cxj.cxj_test_cloud.base.application.BaseApplication;
import com.cxj.cxj_test_cloud.common.di.module.ActivityInjectorModule;
import com.cxj.cxj_test_cloud.common.di.module.AppModule;

import javax.inject.Singleton;

import dagger.BindsInstance;
import dagger.Component;
import dagger.android.AndroidInjectionModule;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;

/**
 * AndroidInjectionModule 是 dagger-android 的“根路由表”，负责把 Activity/Fragment/Application 的注入请求 统一分发到各个 @ContributesAndroidInjector
 * 生成的子组件。不把它放进 @Component(modules={...})，所有页面都无法完成注入，因为 Dagger 找不到“谁去负责把依赖塞进 Activity/Fragment”。
 */

/**
 * @Component 的职责只有 两件事：
 * 1.声明依赖来源（modules = …）
 * 2.声明对外暴露的能力（provision methods / inject methods）  todo  怎么样才能实现对外暴露
 *
 * Component 接口里的“provision 方法”不是“必须与 Module 一一对应”，而是“只要最终依赖图能提供得出来就行”。
 * 写不写这些方法、怎么写，完全取决于 “外部调用方想从 Dagger 里直接拿到什么”。
 */
@Singleton
@Component(modules = {AndroidInjectionModule.class, AppModule.class, ActivityInjectorModule.class})
public interface AppComponent {
    SharedPreferences getSp();

    Retrofit getRetrofit();

    OkHttpClient getOkHttpClient();

    Application getApplication();

    ServerApi getServerApi();

    Context context();

    void inject(BaseApplication application);//todo 注入application

    //todo 怎么理解   跟AppComponent接口又有什么联系
    @Component.Builder   //todo 将参数绑定到依赖图中,表示提前提供 Application 上下文给整个依赖图，让其参与其构建过程
    interface Builder {
        @BindsInstance
        AppComponent.Builder setApplication(Application application);

        AppComponent build();
    }
}
